package com.slipper.util;

import com.slipper.exception.CommonException;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class AESUtil {
    private static final String AES_ECB = "AES/ECB/PKCS5Padding";

    /**
     * 加密
     * */
    public static String encrypt(String text) {
        String key = Tool.randomString(16);
        String sha = Tool.randomString(16);
        String encrypt = encrypt(text, key);
        String md5 = MD5.encode(sha + encrypt + key);
        return sha + md5.substring(0, 16) + key + md5.substring(16) + encrypt;
    }

    /**
     * 加密
     * */
    public static String encrypt(String text, String key) {
        if (Tool.isBlank(text) || Tool.isBlank(key)) {
            return null;
        }

        try {
            Cipher cipher = Cipher.getInstance(AES_ECB);
            SecretKeySpec secretKeySpec = getSecretKeySpec(key);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            byte[] encryptedBytes = cipher.doFinal(getBytes(text));
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            throw new CommonException("加密出错！", e);
        }
    }

    /**
     * 解密
     * */
    public static String decrypt(String text) {
        if (text == null || text.length() <= 64) return null;

        String sha = text.substring(0, 16);
        String md51 = text.substring(16, 32);
        String key = text.substring(32, 48);
        String md52 = text.substring(48, 64);
        String md5 = md51 + md52;
        String encrypt = text.substring(64);

        if (!MD5.encode(sha + encrypt + key).equals(md5)) throw new CommonException("数据已被篡改！");

        return decrypt(encrypt, key);
    }

    /**
     * 解密
     * */
    public static String decrypt(String text, String key) {
        if (Tool.isBlank(text) || Tool.isBlank(key)) {
            return null;
        }
        try {
            byte[] textBytes = Base64.getDecoder().decode(text);
            Cipher cipher = Cipher.getInstance(AES_ECB);
            SecretKeySpec secretKeySpec = getSecretKeySpec(key);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            byte[] decryptedBytes = cipher.doFinal(textBytes);
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new CommonException("解密出错！", e);
        }
    }

    private static byte[] getBytes(String str) {
        return str.getBytes(StandardCharsets.UTF_8);
    }

    private static SecretKeySpec getSecretKeySpec(String key) {
        return new SecretKeySpec(getBytes(key), "AES");
    }

    public static void main(String[] args) {
        String text = "这是字符串";
        String encryptTextCBC = encrypt(text);
        System.out.println("ECB 加密后内容：" + encryptTextCBC);
        System.out.println("ECB 解密后内容：" + decrypt(encryptTextCBC));
    }
}
